const simplego = {
	colors: ["B", "W"],
	positions: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"]
}

class Responsibility {
	constructor() {
		this.next = null;
	}
	handle(request) {
		if (this.next) {
			this.next.handle(request);
		} else {
			return true;
		}
	}
}

class extract_go_manual extends Responsibility {
	constructor() {
		super();
		this.combinedPattern = /[\u4e00-\u9fa5a-zA-Z0-9;\[\]\-： ]+/g;
	}
	handle(text) {
		this.go_list = [];
		var results = text.match(this.combinedPattern) || [];
		var format_content = results.join('').split(";");
		for (var index in format_content) {
			var item = format_content[index];
			if (item.length == 5 && simplego.colors.includes(item[0])) {
				if (simplego.positions.includes(item[2]) && simplego.positions.includes(item[3])) {
					this.go_list.push(item);
				}
			}
		}
		return super.handle(this.go_list);
	}
}

class Filter_Criteria extends Responsibility {
	constructor() {
		super();
		this.goList = [];
		this.list_of_parent = [{}];
		this.parent = {};
	}
	handle(go_list) {
		for (var index in go_list) {
			this.go_handler(go_list[index]);
		}
		return super.handle(this.list_of_parent);
	}
	go_handler(item) {
		this.parent[item.slice(2, 4)] = item[0];
		var del_pos = [];
		var near_pos = this.near_positions(item.slice(2, 4));
		for (var npn in near_pos) {
			if (this.parent.hasOwnProperty(near_pos[npn])) {
				if (this.parent[near_pos[npn]] != this.parent[item.slice(2, 4)]) {
					this.go_string = { 'string': [], 'empty': [] };
					this.go_string_f(near_pos[npn]);
					if (this.go_string['empty'].length == 0) {
						for (var spn in this.go_string['string']) {
							del_pos.includes(this.go_string['string'][spn]) || del_pos.push(this.go_string['string'][spn]);
						}
					}
				}
			}
		}
		if (del_pos.length == 0) {
			this.go_string = { 'string': [], 'empty': [] };
			this.go_string_f(item.slice(2, 4));
			if (this.go_string['empty'].length == 0) {
				delete this.parent[item.slice(2, 4)];
			} else {
				this.goList.push(item);
				this.list_of_parent.push(JSON.parse(JSON.stringify(this.parent)));
			}
		} else {
			for (var d_p in del_pos) {
				delete this.parent[del_pos[d_p]];
			}
			this.goList.push(item);
			this.list_of_parent.push(JSON.parse(JSON.stringify(this.parent)));
		}
	}
	go_string_f(pos) {
		this.go_string['string'].push(pos);
		var near_p = this.near_positions(pos);
		for (var npn in near_p) {
			if (this.parent.hasOwnProperty(near_p[npn])) {
				if (this.parent[near_p[npn]] == this.parent[pos] && !this.go_string['string'].includes(near_p[npn])) {
					this.go_string_f(near_p[npn]);
				}
			} else {
				this.go_string['empty'].includes(near_p[npn]) || this.go_string['empty'].push(near_p[npn]);
			}
		}
	}
	near_positions(position) {
		var near_pos = [];
		var row = this.near(position[0]);
		var col = this.near(position[1]);
		for (var r in row) {
			near_pos.push(row[r] + position[1]);
		}
		for (var c in col) {
			near_pos.push(position[0] + col[c]);
		}
		return near_pos;
	}
	near(char) {
		switch (char) {
			case "a":
				return ["b"];
			case "s":
				return ["r"];
			case "b": case "c": case "d": case "e": case "f": case "g":
			case "h": case "i": case "j": case "k": case "l": case "m":
			case "n": case "o": case "p": case "q": case "r":
			default:
				var pos = simplego.positions.indexOf(char);
				return [simplego.positions[pos - 1], simplego.positions[pos + 1]];
		}
	}
}

function Chain_of_Responsibility_Pattern() {
	const Handle1 = new extract_go_manual();
	const Handle2 = new Filter_Criteria();
	Handle1.next = Handle2;
	Handle1.handle(sgftext);
	Handle2.handle(["B[aa]"]);
	console.log(Handle2.list_of_parent);
}

const sgftext = `(;CA[UTF-8]AP[YuanYu]GM[1]FF[4]
SZ[19]
GN[2018腾讯世界人工智能围棋大赛决赛第1局 30日10：00]
DT[2018-07-30]
PB[Golaxy]BR[9d]
PW[FineArt]WR[9d]
KM[7.5]HA[0]RU[Chinese]RE[W+R]TM[3600]TC[10]TT[60]
;B[qd];W[pp];B[dd];W[dp];B[qn];W[qo];B[pn];W[np];B[pj];W[od];B[lc]
;W[me];B[lq];W[qe];B[fq];W[cc];B[qq];W[rn];B[cd];W[dc];B[ed];W[ec]
;B[rm];W[or];B[ro];W[rp];B[qp];W[po];B[sn];W[rq];B[fc];W[fb];B[cn]
;W[er];B[bc];W[bb];B[eb];W[db];B[gb];W[pd];B[eo];W[co];B[bn];W[fp]
;B[ep];W[eq];B[do];W[cq];B[fr];W[iq];B[hp];W[gq];B[gp];W[fo];B[fn]
;W[go];B[hn];W[gr];B[gn];W[fs];B[ei];W[bd];B[be];W[ac];B[cf];W[ih]
;B[qc];W[rf];B[pf];W[qh];B[ob];W[nb];B[oc];W[pc];B[pb];W[rd];B[nd]
;W[qb];B[oe];W[rc];B[nc];W[if];B[hg];W[ig];B[je];W[gi];B[fg];W[hf]
;B[fj];W[lg];B[lf];W[mg];B[kg];W[kh];B[mf];W[ff];B[gg];W[fd];B[gc]
;W[hd];B[fe];W[gd];B[ic];W[gj];B[kf];W[bg];B[cg];W[kj];B[bo];W[gk]
;B[fk];W[id];B[jc];W[eh];B[fh];W[fi];B[ej];W[fl];B[el];W[gl];B[lo]
;W[ae];B[bh];W[em];B[dl];W[km];B[ho];W[qk];B[ol];W[bf];B[ce];W[gf]
;B[ef];W[qj];B[hq];W[hr];B[pi];W[qi];B[lk];W[kk];B[lh];W[li];B[mh]
;W[ng];B[oo];W[pq];B[og];W[nh];B[mi];W[oh];B[qr];W[rr];B[mj];W[ph]
;B[lm];W[kl];B[jh];W[ki];B[bq];W[hh];B[eg];W[ll];B[ml];W[no];B[ln]
;W[nk];B[mk];W[nm];B[nn];W[mm];B[nl];W[mn];B[om];W[mo];B[jq];W[rl]
;B[ql];W[pl];B[qm];W[ir];B[jn];W[pk];B[rk];W[on];B[pm];W[rj];B[sl]
;W[cr];B[jg];W[ji];B[hl];W[il];B[hm];W[jp];B[kp];W[kn];B[ko];W[ik]
;B[cp];W[jr];B[jo];W[hc];B[hb];W[ea];B[af];W[ag];B[fq];W[br];B[ar]
;W[lr];B[mr];W[kq];B[mq];W[ad];B[ah];W[af];B[fm];W[sp];B[nn];W[op]
;B[dq];W[dr];B[jm];W[jl];B[ls];W[on];B[kr];W[nf];B[ne];W[ok];B[hk]
;W[hj];B[pg];W[jd])`

var list_of_bg_color = ["AliceBlue", "AntiqueWhite", "Aqua", "Aquamarine", "Azure"]
list_of_bg_color.push("Beige", "Bisque", "Black", "BlanchedAlmond", "Blue", "BlueViolet", "Brown", "BurlyWood")
list_of_bg_color.push("CadetBlue", "Chartreuse", "Chocolate", "Coral", "CornflowerBlue", "Cornsilk", "Crimson", "Cyan")
list_of_bg_color.push("DarkBlue", "DarkCyan", "DarkGoldenRod", "DarkGray", "DarkGreen", "DarkKhaki", "DarkMagenta", "DarkOliveGreen", "DarkOrange")
list_of_bg_color.push("DarkOrchid", "DarkRed", "DarkSalmon", "DarkSeaGreen", "DarkSlateBlue", "DarkSlateGray", "DarkTurquoise", "DarkViolet")
list_of_bg_color.push("DeepPink", "DeepSkyBlue", "DimGray", "DodgerBlue", "FireBrick", "FloralWhite", "ForestGreen", "Fuchsia")
list_of_bg_color.push("Gainsboro", "GhostWhite", "Gold", "GoldenRod", "Gray", "Green", "GreenYellow", "HoneyDew", "HotPink", "IndianRed ", "Indigo ", "Ivory", "Khaki")
list_of_bg_color.push("Lavender", "LavenderBlush", "LawnGreen", "LemonChiffon", "LightBlue", "LightCoral", "LightCyan", "LightGoldenRodYellow")
list_of_bg_color.push("LightGray", "LightGreen", "LightPink", "LightSalmon", "LightSeaGreen", "LightSkyBlue", "LightSlateGray", "LightSteelBlue")
list_of_bg_color.push("LightYellow", "Lime", "LimeGreen", "Linen", "Magenta", "Maroon", "MediumAquaMarine", "MediumBlue", "MediumOrchid", "MediumPurple")
list_of_bg_color.push("MediumSeaGreen", "MediumSlateBlue", "MediumSpringGreen", "MediumTurquoise", "MediumVioletRed", "MidnightBlue", "MintCream")
list_of_bg_color.push("MistyRose", "Moccasin", "NavajoWhite", "Navy", "OldLace", "Olive", "OliveDrab", "Orange", "OrangeRed", "Orchid")
list_of_bg_color.push("PaleGoldenRod", "PaleGreen", "PaleTurquoise", "PaleVioletRed", "PapayaWhip", "PeachPuff", "Peru", "Pink", "Plum", "PowderBlue", "Purple")
list_of_bg_color.push("Red", "RosyBrown", "RoyalBlue", "SaddleBrown", "Salmon", "SandyBrown", "SeaGreen", "SeaShell", "Sienna", "Silver", "SkyBlue")
list_of_bg_color.push("SlateBlue", "SlateGray", "Snow", "SpringGreen", "SteelBlue")
list_of_bg_color.push("Tan", "Teal", "Thistle", "Tomato", "Turquoise", "Violet", "Wheat", "White", "WhiteSmoke", "Yellow", "YellowGreen")

function ascii_to_number(character) {
	if (character.length == 1) {
		if (character.match(/[A-Z]/)) {
			return character.charCodeAt() - 'A'.charCodeAt();
		} else if (character.match(/[a-z]/)) {
			return character.charCodeAt() - 'a'.charCodeAt();
		}
	}
	return -1;
}

function differenceObjects(obj1, obj2) {
	let result = {};
	Object.keys(obj1).forEach(key => {
		if (!(key in obj2)) {
			result[key] = obj1[key];
		}
	});
	return result;
}

function go_main(action) {
	switch (action) {
		case "悔棋":
			delete simplego_Handle2.parent[simplego_Handle2.goList.pop().slice(2, 4)];
			var d_pos = differenceObjects(simplego_Handle2.list_of_parent.at(-2), simplego_Handle2.list_of_parent.at(-1));
			if (Object.keys(d_pos).length > 0) {
				for (var key in d_pos) {
					simplego_Handle2.parent[key] = d_pos[key];
				}
			}
			simplego_Handle2.list_of_parent.pop();
			quick_browsing--;
			change_color(simplego_Handle2.parent);
			change_player();
			break;
		case "新开局":
			if (confirm("确定新开局吗？")) {
				console.clear()
				status_bar = ["游戏健康忠告：请注意休息，合理安排游戏时间。"];
				simplego_Handle1 = new extract_go_manual();
				simplego_Handle2 = new Filter_Criteria();
				simplego_Handle1.next = simplego_Handle2;
				change_color({});
				go_player = "B";
				cruise_control_switch = false;
				$("#cruise-control span:eq(0)").removeClass("btn-info");
				$("#cruise-control span:eq(0)").addClass("btn-primary");
				$("#cruise-control span:eq(1)").text(2);
				$("#cruise-control input").val(2);
				quick_browsing = 0;
				$("#quick-browsing span:eq(1)").text(0);
				$("#quick-browsing input").val(0);
				$("#quick-browsing input").attr("max", 0);
			} else {
				alert("请继续下棋！")
			}
			break;
		case "下载棋谱记录":
			if (status_bar.length > 1) {
				const jsonString = JSON.stringify(status_bar);
				const blob = new Blob([jsonString], { type: 'application/json' });
				const url = URL.createObjectURL(blob);
				const link = document.createElement('a');
				link.href = url;
				const now = new Date();
				link.setAttribute('download', '棋谱记录-' + now.getFullYear() + now.getMonth() + now.getDate() + '.json');
				document.body.appendChild(link);
				link.click();
				document.body.removeChild(link);
				console.log('成功下载文件：棋谱记录-' + now.getFullYear() + now.getMonth() + now.getDate() + '.json');
			}
			break;
		default:
			console.log(action);;
	}
}

/*
var simplego = new SimpleGo();
simplego.extract_go_manual(sgftext);
*/

var simplego_Handle1 = new extract_go_manual();
var simplego_Handle2 = new Filter_Criteria();
simplego_Handle1.next = simplego_Handle2;